package com.ruoqing.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoqing.core.constant.Constants;
import com.ruoqing.core.constant.ErrorConstants;
import com.ruoqing.core.constant.Oauth2ModeConstants;
import com.ruoqing.core.domain.rqadmin.BanUserPo;
import com.ruoqing.core.domain.rquser.UserEntity;
import com.ruoqing.core.dto.BaseResponse;
import com.ruoqing.core.dto.auth.AuthDto;
import com.ruoqing.core.dto.auth.LoginUserDto;
import com.ruoqing.core.dto.user.UserRegisterDto;
import com.ruoqing.core.exception.SmsException;
import com.ruoqing.core.vo.auth.AuthResponseVo;
import com.ruoqing.core.vo.inform.SmsResponseVo;
import com.ruoqing.inform.constant.sms.SmsTemplateEnum;
import com.ruoqing.inform.constant.sms.SmsTitleEnum;
import com.ruoqing.system.rest.Oauth2UserLogin;
import com.ruoqing.user.dao.UserDao;
import com.ruoqing.user.feign.PhoneCodeServiceFeign;
import com.ruoqing.user.feign.UserStandardServiceFeign;
import com.ruoqing.user.service.api.UserRegisterService;
import com.ruoqing.user.utils.GenerateCode;
import com.ruoqing.utils.common.Md5Encryption;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
	* @author YaoXian
	* @title: UserRegisterServiceImpl
	* @projectName ruoxi-blog
	* @description: 若兮微服务 - 用户服务 - 用户注册接口实现类
	* @date 2020-11-06 22:08
	*/
@Service
@Slf4j
public class UserRegisterServiceImpl implements UserRegisterService {

		@Resource
		private PhoneCodeServiceFeign phoneCodeServiceFeign;

		@Resource
		private UserDao userDao;

		@Resource
		private RedisTemplate<String,String> redisTemplate;

		@Resource
		private UserStandardServiceFeign userStandardServiceFeign;
		
		@Resource
		private Oauth2UserLogin oauth2UserLogin;
		
		@Resource
		private RocketMQTemplate rockerMqTemplate;

		@Resource
		private GenerateCode generateCode;
		
		@Value("${oauth2.client_id}")
		private String clientId;
		
		@Value("${oauth2.client_secret}")
		private String clientSecret;

		@Override
		public SmsResponseVo registerGetPhoneCode(String phoneNumber) {

				BanUserPo offendUser = userStandardServiceFeign.findOffendUser(phoneNumber);
				SmsResponseVo smsResponseVo = new SmsResponseVo();
				if (StringUtils.isEmpty(offendUser)){
						final String code = generateCode.getCode();
						try {
								smsResponseVo = phoneCodeServiceFeign.sendMobileCode(phoneNumber,
												SmsTitleEnum.siteName.getBody(),
												SmsTemplateEnum.loginCodeSmsBody.getCodeId(),
												code);
						} catch (Exception e) {
								throw SmsException.buildSmsException(Constants.responseError, ErrorConstants.SEND_CODE_ERROR);
						}
						if (smsResponseVo.getMessage().contains("触发天级流控")){
								smsResponseVo.setMessage("当天发送手机注册验证码次数已达上限!");
								smsResponseVo.setStatus(Constants.responseError);
						}else {
								if (Constants.responseOk.equals(smsResponseVo.getStatus())){
										redisTemplate.boundValueOps("code"+phoneNumber).set(smsResponseVo.getCode());
										redisTemplate.expire("code"+phoneNumber,1, TimeUnit.MINUTES);
										log.info("手机号为*"+phoneNumber+"*的用户发送用于注册用户" +
														"的验证码将于60秒后失效");
										smsResponseVo.setMessage("发送注册验证码成功,1分钟内有效!");
										smsResponseVo.setPhoneNumber(phoneNumber);
								}else {
										smsResponseVo.setMessage("发送注册验证码失败,请稍后重试!");
								}
						}
				}else {
						smsResponseVo.setStatus(Constants.responseError);
						smsResponseVo.setMessage("违规手机号,无法申请注册!");
				}
						return smsResponseVo;
				}

		@Override
		public BaseResponse checkRegisterCode(String code, String phoneNumber) {

				String msg;
				String status;
				String smsCode = redisTemplate.boundValueOps("code"+phoneNumber).get();
				if (!StringUtils.isEmpty(smsCode)){
						if (code.equals(smsCode)){
								redisTemplate.delete("code"+phoneNumber);
								msg = "验证码校验成功!";
								status = Constants.responseOk;
						}else {
								msg = "验证码有误!";
								status = Constants.responseError;
						}
				}else {
						msg = "验证码已失效!";
						status = Constants.responseError;
				}
				return BaseResponse.buildResponse(status,msg);
		}

		@Override
		@Transactional(rollbackFor = Exception.class)
		public BaseResponse userRegister(UserRegisterDto userRegisterDto) {
				BaseResponse baseResponse = new BaseResponse();
				QueryWrapper<UserEntity> queryWrapper = new QueryWrapper<UserEntity>();
				List<UserEntity> userList = userDao.selectList(queryWrapper);
				for (UserEntity user : userList) {
						if (user.getUsername().equals(userRegisterDto.getUsername())){
								baseResponse.setStatus(Constants.responseError);
								baseResponse.setMessage("用户名已存在!");
								return baseResponse;
						}
				}
				String password = Md5Encryption.encryption(userRegisterDto.getPassword());
				userRegisterDto.setPassword(password);
				UserEntity userEntity = new UserEntity();
				userEntity.setEmail(userRegisterDto.getEmail());
				userEntity.setUsername(userRegisterDto.getUsername());
				userEntity.setQqNumber(userRegisterDto.getQqNumber());
				userEntity.setPassword(userRegisterDto.getPassword());
				userEntity.setPhoneNumber(userRegisterDto.getPhoneNumber());
				userDao.insert(userEntity);
				baseResponse.setStatus(Constants.responseOk);
				baseResponse.setMessage("注册成功!");
//				rockerMqTemplate.asyncSend("user_topic:register",
//								UserMessageDto.buildUserMessageDto(UserResponse.buildUserResponse
//																(baseResponse.getStatus(),baseResponse.getMessage(),userEntity),
//												UserMessageEnum.register),new MySendCallback());
				log.info("用户名为 "+ userRegisterDto.getUsername()+" 的用户已创建成功!");
				return baseResponse;
		}
		
		@Override
		public AuthResponseVo userLogin(LoginUserDto loginUserDto) {
				if (StringUtils.isEmpty(loginUserDto)){
						return AuthResponseVo.buildAuthResponseVo(Constants.responseError,"非法登录信息!");
				}
				AuthDto authDto = oauth2UserLogin.getUserToken(
								Oauth2ModeConstants.PASSWORD,
								clientId, clientSecret, loginUserDto);
				if (authDto.getStatus().equals(Constants.responseOk)){
						return AuthResponseVo.buildAuthResponseVo(authDto.getStatus(),"登录成功",
										authDto.getTokenDto().getAccess_token());
				}else {
						return AuthResponseVo.buildAuthResponseVo(authDto.getStatus(),
										authDto.getMessage());
				}
		}
		
}
